package com.seleniti.enpareja.controller.ui.view;

import org.ioc.commons.flowcontrol.actioncontroller.ActionController;
import org.ioc.commons.flowcontrol.common.impl.ReceiverAdapter;
import org.ioc.commons.flowcontrol.eventbus.EventBus;
import org.ioc.commons.flowcontrol.logincontroller.IsLoggedUserInfoConsumer;
import org.ioc.commons.flowcontrol.operationmanager.OperationManager;
import org.ioc.commons.flowcontrol.operationmanager.impl.OperationHandlerFactory;
import org.ioc.commons.utils.FormatterLogger;

import com.seleniti.enpareja.controller.common.domain.LoggedUserInfo;
import com.seleniti.enpareja.controller.control.place.EnParejaPlace;
import com.seleniti.enpareja.controller.model.integration.database.domain.Couple;
import com.seleniti.enpareja.controller.model.integration.database.domain.CoupleType;
import com.seleniti.enpareja.controller.ui.base.EnParejaViewBasePresenter;
import com.seleniti.enpareja.controller.ui.view.MainView.Action;
import com.seleniti.enpareja.controller.ui.view.MainView.Event;
import com.seleniti.enpareja.controller.ui.view.MainView.Operation;

/**
 * Presenter for the Login view
 * 
 * @author Jesús Lunar Pérez
 * 
 */
public class MainViewPresenter extends
		EnParejaViewBasePresenter<MainView, MainView.Event, MainView.Operation, MainView.Action> implements
		MainView.Presenter, IsLoggedUserInfoConsumer<LoggedUserInfo> {

	private static final FormatterLogger logger = FormatterLogger.getLogger(MainViewPresenter.class);

	public MainViewPresenter(MainView display, EventBus<Event> eventbus, OperationManager<Operation> operationManager,
			ActionController<Action> actionController) {
		super(display, eventbus, operationManager, actionController);
	}

	@Override
	public void onInitDisplay() {
		super.onInitDisplay();

		shell.gettingStartedInfoVisible().setVisible(false);
	}

	@Override
	public void onLoggedUserInfoNotReadyYet() {
		display.setEnabled(false);
	}

	@Override
	protected void bindComponents() {
		super.bindComponents();

		display.operationManager().bindOperation(Operation.GettingData,
				OperationHandlerFactory.<Operation> forLoaders(shell.globalLoader()));
	}

	@Override
	public void onActive() {
		super.onActive();

		this.loginController.requiresLoggedUserInfoIfDisplayActive(this);

		logger.info("Activating Main view ");

		refreshData();

		shell.goBackButtonVisible().setVisible(false);
		shell.refreshButtonVisibility().setVisible(false);
	}

	@Override
	public void onDeactive() {
		super.onDeactive();

		logger.info("Deactivating Main view ");
	}

	@Override
	protected void refreshData() {
		if (display.isActive()) {
			refreshLoggedUserInfo();
			if (!operationManager.isOpPending(Operation.GettingData)) {
				super.refreshData();

				super.refreshCouple(
						new ReceiverAdapter<Couple>() {

							@Override
							public void success(Couple result) {
								display.pendingShoppingList().setValue(
										result != null ? result.getPendingShoppingListElements() : null);
								display.pendingHomeTasks().setValue(
										result != null ? result.getPendingHomeTasks() : null);
								display.pendingProducts().setValue(result != null ? result.getPendingProducts() : null);
							}
						}, Operation.GettingData, operationManager, "pendingShoppingListElements", "pendingHomeTasks",
						"pendingProducts");
			}
		}
	}

	@Override
	public void onLoggedUserInfoDataReady() {
		if (display.isActive()) {
			refreshData();
		}
	}

	@Override
	public void onLoggedUserInfoDataUpdated(LoggedUserInfo loggedUserInfo) {
		if (display.isActive()) {
			logger.info("On global data {0} updated", loggedUserInfo);
			refreshLoggedUserInfo();
		}
	}

	private void refreshLoggedUserInfo() {
		logger.info("Refreshing logged user info");
		LoggedUserInfo lui = this.loginController.getLoggedUserInfo();

		display.setEnabled(lui != null && lui.getCoupleName() != null && !lui.getCoupleName().isEmpty());

		boolean rejectedRequestsFromYou = lui != null && lui.isSomeRejectedRequestsFromYou();
		boolean requestsToYou = !rejectedRequestsFromYou && lui != null && lui.isSomeCoupleRequestsToYou();
		boolean pendingRequestsFromYou = !requestsToYou && !rejectedRequestsFromYou && lui != null
				&& lui.isSomePendingRequestsFromYou();
		boolean nonAssociated = !requestsToYou && !rejectedRequestsFromYou && !pendingRequestsFromYou && lui != null
				&& lui.isLogged() && (lui.getCoupleName() == null || lui.getCoupleName().isEmpty() || lui.getCoupleType()==CoupleType.TESTING_MODE_COUPLE);

		shell.rejectedRequestsFromYouPanelVisibility().setVisible(rejectedRequestsFromYou);
		shell.requestsToYouPanelVisibility().setVisible(requestsToYou);
		shell.pendingRequestsFromYouPanelVisibility().setVisible(pendingRequestsFromYou);
		shell.nonAssociatedPanelVisibility().setVisible(nonAssociated);

		shell.firstStepsVisibility().setVisible(shell.nonAssociatedPanelVisibility().isVisible() && lui.getCoupleType()!=CoupleType.TESTING_MODE_COUPLE);
		shell.nonAssociatedButtonVisibility().setVisible(!shell.firstStepsVisibility().isVisible());

		boolean requiresConfig = (lui != null && lui.getGender() == null && lui.getUserEmail() != null
				&& lui.getUserName() != null && lui.getUserEmail().startsWith(lui.getUserName()));
		display.configUserSuggestionPanelVisibility().setVisible(requiresConfig);
	}

	@Override
	public void onGoToShoppingListView() {
		this.placeController.goTo(EnParejaPlace.ShoppingList);
	}

	@Override
	public void onGoToHomeTasksView() {
		this.placeController.goTo(EnParejaPlace.HomeTasks);
	}

	@Override
	public void onGoToMealsView() {
		this.placeController.goTo(EnParejaPlace.Meals);
	}

	@Override
	public void onGoToWorkShiftsView() {
		this.placeController.goTo(EnParejaPlace.WorkShifts);
	}

	@Override
	public void onGoToPendingShoppingView() {
		this.placeController.goTo(EnParejaPlace.PendingShopping);
	}

	@Override
	public void onGoToSharedCostView() {
		this.placeController.goTo(EnParejaPlace.SharedExpenses);
	}

	@Override
	public void onGoSettings() {
		this.placeController.goTo(EnParejaPlace.UserSettings, true, "", false);
	}

}
